package com.example.test;

public class DeadlockExample {
    private final Object lock1 = new Object();
    private final Object lock2 = new Object();

    /**
     * 死锁的四个必要条件（四个条件同时成立才会发生死锁）：
     * 互斥：线程对资源的独占性
     * 占有且等待：一个线程持有锁，同时等待另一个锁
     * 不可抢占：线程获得的锁不能被其他线程强制抢占
     * 循环等待：两个线程形成“你等我、我等你”的闭环
     */
    public void deadlockExample() {
        /**
         * 线程1
         */
        Thread t1 = new Thread(() -> {
            /**
             * 必须在持有 lock1 的情况下再试图获取 lock2，才符合“占有且等待”的条件。
             */
            synchronized (lock1) {
                System.out.println("线程1获取锁1");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (lock2) {
                    System.out.println("线程1获取锁2");
                }
            }
        });

        /**
         * 线程2
         */
        Thread t2 = new Thread(() -> {
            synchronized (lock2) {
                System.out.println("线程2获取锁2");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (lock1) {
                    System.out.println("线程2获取锁1");
                }
            }
        });

        t1.start();
        t2.start();
    }

    public static void main(String[] args) {
        new DeadlockExample().deadlockExample();
    }

}
